// ============================================
// 09 - 包和模块 (Packages and Modules)
// ============================================

/// Rust 的模块系统包括:
/// - 包 (Packages): Cargo 的功能，构建、测试和分享 crate
/// - Crate: 一个模块的树形结构，形成库或二进制项目
/// - 模块 (Modules): 控制作用域和私有性
/// - 路径 (Paths): 命名项的方式

// ==================== 模块基础 ====================

/// 定义模块
/// 使用 mod 关键字定义模块
pub fn module_basics() {
    println!("\n=== 模块基础 ===");
    
    // 调用模块中的函数
    garden::plant_flower();
    garden::tools::water_plants();
}

mod garden {
    // 模块中的项默认是私有的
    pub fn plant_flower() {
        println!("种植花朵");
        prepare_soil(); // 可以调用同模块的私有函数
    }
    
    fn prepare_soil() {
        println!("准备土壤");
    }
    
    // 嵌套模块
    pub mod tools {
        pub fn water_plants() {
            println!("浇水");
        }
        
        fn _trim_plants() {
            println!("修剪植物");
        }
    }
}

// ==================== 路径 ====================

/// 引用模块中的项
pub fn module_paths() {
    println!("\n=== 模块路径 ===");
    
    // 绝对路径 - 从 crate 根开始
    // crate::garden::plant_flower();
    
    // 相对路径 - 从当前模块开始
    garden::plant_flower();
    
    // 访问嵌套模块
    garden::tools::water_plants();
}

// ==================== use 关键字 ====================

/// 使用 use 关键字引入路径
pub fn use_keyword() {
    println!("\n=== use 关键字 ===");
    
    use garden::plant_flower;
    use garden::tools::water_plants;
    
    plant_flower();
    water_plants();
}

/// use 的惯用模式
pub fn use_idioms() {
    println!("\n=== use 惯用模式 ===");
    
    // 对于函数，通常引入父模块
    use garden::plant_flower;
    plant_flower();
    
    // 对于结构体、枚举，通常引入完整路径
    use std::collections::HashMap;
    let mut map = HashMap::new();
    map.insert(1, 2);
    println!("HashMap: {:?}", map);
    
    // 使用 as 提供别名
    use std::fmt::Result;
    use std::io::Result as IoResult;
    
    fn _function1() -> Result {
        Ok(())
    }
    
    fn _function2() -> IoResult<()> {
        Ok(())
    }
}

/// 使用 pub use 重导出
pub fn pub_use() {
    println!("\n=== pub use 重导出 ===");
    
    println!("pub use 可以将内部结构重新导出");
    println!("使外部代码可以使用更方便的路径");
}

// 示例: 重导出
pub mod hosting {
    pub fn add_to_waitlist() {
        println!("添加到等待列表");
    }
}

// 重导出，外部可以直接使用
pub use hosting::add_to_waitlist;

/// 嵌套路径
pub fn nested_paths() {
    println!("\n=== 嵌套路径 ===");
    
    // 不使用嵌套路径
    // use std::io;
    // use std::cmp::Ordering;
    
    // 使用嵌套路径
    use std::{cmp::Ordering, io};
    
    println!("嵌套路径可以减少 use 语句的数量");
    
    // 合并共同路径
    // use std::io;
    // use std::io::Write;
    
    // 使用 self
    use std::io::Write;
    
    let _result = Ordering::Less;
    let _stdout = io::stdout();
}

/// glob 运算符
pub fn glob_operator() {
    println!("\n=== glob 运算符 ===");
    
    // 将所有公有定义引入作用域
    use std::collections::*;
    
    let _map: HashMap<i32, i32> = HashMap::new();
    let _set: HashSet<i32> = HashSet::new();
    
    println!("使用 * 可以引入所有公有项");
    println!("但要小心命名冲突");
}

// ==================== 模块组织 ====================

/// 将模块分割到不同文件
pub fn module_files() {
    println!("\n=== 模块文件组织 ===");
    
    println!("文件组织方式:");
    println!("1. src/lib.rs 或 src/main.rs 是 crate 根");
    println!("2. 声明模块: mod garden;");
    println!("3. Rust 会在以下位置查找模块代码:");
    println!("   - 内联在 mod garden 后的大括号中");
    println!("   - src/garden.rs 文件");
    println!("   - src/garden/mod.rs 文件");
}

// ==================== 可见性规则 ====================

/// 公有性规则
pub fn visibility_rules() {
    println!("\n=== 可见性规则 ===");
    
    println!("1. 默认情况下，所有项都是私有的");
    println!("2. 使用 pub 关键字使项变为公有");
    println!("3. 父模块不能访问子模块的私有项");
    println!("4. 子模块可以访问祖先模块的所有项");
}

mod back_of_house {
    pub struct Breakfast {
        pub toast: String,        // 公有字段
        seasonal_fruit: String,   // 私有字段
    }
    
    impl Breakfast {
        pub fn summer(toast: &str) -> Breakfast {
            Breakfast {
                toast: String::from(toast),
                seasonal_fruit: String::from("桃子"),
            }
        }
    }
    
    // 枚举的成员默认公有
    pub enum Appetizer {
        Soup,
        Salad,
    }
}

pub fn struct_visibility() {
    println!("\n=== 结构体可见性 ===");
    
    let mut meal = back_of_house::Breakfast::summer("黑麦");
    meal.toast = String::from("小麦");
    println!("我想要 {} 土司", meal.toast);
    
    // meal.seasonal_fruit = String::from("蓝莓"); // ❌ 私有字段
    
    let _order1 = back_of_house::Appetizer::Soup;
    let _order2 = back_of_house::Appetizer::Salad;
}

// ==================== super 关键字 ====================

/// 使用 super 访问父模块
pub fn super_keyword() {
    println!("\n=== super 关键字 ===");
    
    kitchen::serve_order();
}

fn deliver_order() {
    println!("配送订单");
}

mod kitchen {
    pub fn serve_order() {
        cook_order();
        super::deliver_order(); // 使用 super 访问父模块
    }
    
    fn cook_order() {
        println!("烹饪订单");
    }
}

// ==================== 实际应用示例 ====================

/// 餐厅模块示例
pub mod restaurant {
    pub mod front_of_house {
        pub mod hosting {
            pub fn add_to_waitlist() {
                println!("添加到等待列表");
            }
            
            pub fn seat_at_table() {
                println!("安排座位");
            }
        }
        
        pub mod serving {
            pub fn take_order() {
                println!("接受订单");
            }
            
            pub fn serve_order() {
                println!("上菜");
            }
            
            pub fn take_payment() {
                println!("收款");
            }
        }
    }
    
    pub fn eat_at_restaurant() {
        // 绝对路径
        crate::modules::restaurant::front_of_house::hosting::add_to_waitlist();
        
        // 相对路径
        front_of_house::hosting::seat_at_table();
        front_of_house::serving::take_order();
        front_of_house::serving::serve_order();
        front_of_house::serving::take_payment();
    }
}

pub fn practical_example() {
    println!("\n=== 实际应用: 餐厅系统 ===");
    
    restaurant::eat_at_restaurant();
}

// ==================== 模块最佳实践 ====================

/// 模块组织最佳实践
pub fn best_practices() {
    println!("\n=== 模块最佳实践 ===");
    
    println!("1. 按功能组织模块，而不是按文件");
    println!("2. 使用 pub use 提供清晰的公共 API");
    println!("3. 保持模块层次简单");
    println!("4. 使用 mod.rs 或同名文件组织子模块");
    println!("5. 合理使用 pub 控制可见性");
    println!("6. 使用 use 简化路径引用");
}

// ==================== Cargo 工作空间 ====================

/// Cargo 工作空间
pub fn cargo_workspaces() {
    println!("\n=== Cargo 工作空间 ===");
    
    println!("工作空间特性:");
    println!("1. 包含多个相关包的项目");
    println!("2. 共享 Cargo.lock 和输出目录");
    println!("3. 在根目录 Cargo.toml 中定义:");
    println!("   [workspace]");
    println!("   members = [");
    println!("       \"package1\",");
    println!("       \"package2\",");
    println!("   ]");
}

// ==================== 外部包 ====================

/// 使用外部包
pub fn external_packages() {
    println!("\n=== 使用外部包 ===");
    
    println!("1. 在 Cargo.toml 中添加依赖:");
    println!("   [dependencies]");
    println!("   rand = \"0.8.5\"");
    println!("");
    println!("2. 使用 use 引入:");
    println!("   use rand::Rng;");
    println!("");
    println!("3. 标准库 std 也是 crate，但不需要修改 Cargo.toml");
}

/// 主函数 - 演示所有功能
#[allow(dead_code)]
pub fn main() {
    println!("╔════════════════════════════════════════╗");
    println!("║   Rust 包和模块教程                    ║");
    println!("╚════════════════════════════════════════╝");
    
    module_basics();
    module_paths();
    use_keyword();
    use_idioms();
    pub_use();
    nested_paths();
    glob_operator();
    module_files();
    visibility_rules();
    struct_visibility();
    super_keyword();
    practical_example();
    best_practices();
    cargo_workspaces();
    external_packages();
    
    println!("\n✅ 包和模块教程完成！");
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_module_function() {
        garden::plant_flower();
    }
    
    #[test]
    fn test_nested_module() {
        garden::tools::water_plants();
    }
}

